home *** CD-ROM | disk | FTP | other *** search
/ Hot Super Models / Hot Super Models.iso / unix / x11 / xv200.tar / xv-2.00 / unsupt / pcx < prev    next >
Text File  |  1992-01-01  |  13KB  |  524 lines

  1. (Message /usr/users/bradley/Mail/inbox:16)
  2. Return-Path: kong@carmel.ccmail.com
  3. Posted-Date: Wed, 13 Nov 91 17:22:52 PST
  4. Received-Date: Wed, 13 Nov 91 20:17:28 EST
  5. Received: from carmel.ccmail.com by blinky.ccmail.com (4.1/SMI-4.1)
  6.     id AA05996; Wed, 13 Nov 91 17:19:29 PST
  7. Received: by carmel.ccmail.com (4.1/SMI-4.1)
  8.     id AA19879; Wed, 13 Nov 91 17:22:52 PST
  9. Date: Wed, 13 Nov 91 17:22:52 PST
  10. From: kong@carmel.ccmail.com (Ken Chu)
  11. Message-Id: <9111140122.AA19879@carmel.ccmail.com>
  12. To: bradley@grip.cis.upenn.edu
  13. Subject: PCX support for XV (Was Re: extensions to XV)
  14. Content-Type: X-sun-attachment
  15.  
  16. ----------
  17. X-Sun-Data-Type: text
  18. X-Sun-Data-Description: text
  19. X-Sun-Data-Name: text
  20. X-Sun-Content-Lines: 9
  21.  
  22. John,
  23.  
  24. Attached are the .c and .h files for adding PCX support to XV.  I didn't include the modified Makefile or xv.[ch] files, because they were only modifed according to your README.  The code is a combination of xloadimage and pcxtoppm.  I have tested it with all the different types of PCX files I could find, but you may want to try some more yourself (something exotic like PCX with 2 bits/pixel).
  25.  
  26. I look forward to hearing about the new release of XV.
  27.  
  28. Ken
  29.  
  30. P.S. If you are not using Sun's Mail Tool V3, the attached files may be troublesome to extract.  If that is the case, let me know and I'll mail them to you separately.
  31. ----------
  32. X-Sun-Data-Type: h-file
  33. X-Sun-Data-Description: h-file
  34. X-Sun-Data-Name: pcx.h
  35. X-Sun-Content-Lines: 37
  36.  
  37. #ifndef pcx_h
  38. #define pcx_h
  39.  
  40. /*
  41.  * defines for the PCX header and magic numbers
  42.  */
  43.  
  44. typedef struct {                        /*header for PCX bitmap files*/
  45.     unsigned char    signature;            /*PCX file identifier*/
  46.     unsigned char    version;            /*version compatibility level*/
  47.     unsigned char    encoding;            /*encoding method*/
  48.     unsigned char    bitsperpix;            /*bits per pixel, or depth*/
  49.     unsigned short    Xleft;                /*X position of left edge*/
  50.     unsigned short    Ytop;                /*Y position of top edge*/
  51.     unsigned short    Xright;                /*X position of right edge*/
  52.     unsigned short    Ybottom;            /*Y position of bottom edge*/
  53.     unsigned short    Xscreensize;        /*X screen res of source image*/
  54.     unsigned short    Yscreensize;        /*Y screen res of source image*/
  55.     unsigned char    PCXpalette[16][3];    /*PCX color map*/
  56.     unsigned char    reserved1;            /*should be 0, 1 if std res fax*/
  57.     unsigned char    planes;                /*bit planes in image*/
  58.     unsigned short    linesize;            /*byte delta between scanlines */
  59.     unsigned short    paletteinfo;        /*0 == undef
  60.                                           1 == color
  61.                                           2 == grayscale*/
  62.     unsigned char reserved2[58];        /*fill to struct size of 128*/
  63. } PCX_HEADER;
  64.  
  65. #define PCX_HEADERSIZE        128
  66.  
  67. #define PCX_LAST_VER        5            /* last acceptable version number */
  68. #define PCX_RLL                1            /* PCX RLL encoding method */
  69.  
  70. #define PCX_MAGIC            0x0a        /* first byte of a PCX image */
  71. #define PCX_256COLORS_MAGIC    0x0c        /* first byte of a PCX 256 color map */
  72.  
  73. #endif /* pcx_h */
  74. ----------
  75. X-Sun-Data-Type: c-file
  76. X-Sun-Data-Description: c-file
  77. X-Sun-Data-Name: xvpcx.c
  78. X-Sun-Content-Lines: 444
  79.  
  80. /*
  81.  * xvpcx.c - load routine for 'pcx' format pictures.
  82.  *
  83.  * by Ken Chu (kong@carmel.ccmail.com), as derived from pbmplus and xloadimage.
  84.  *    November 11, 1991.
  85.  *
  86.  * LoadPCX(fname, numcols)  -  loads a PCX image file.
  87.  *    numcols is not used as PCX doesn't support 24-bit colors.
  88.  *
  89.  * Assumes the input byte stream is in Intel's byte order.
  90.  *
  91.  */
  92. /*
  93.  *    Permission to use, copy, modify, and distribute this software and its
  94.  *    documentation for any purpose and without fee is hereby granted, provided
  95.  *    that the above copyright notice appear in all copies and that both that
  96.  *    copyright notice and this permission notice appear in supporting
  97.  *    documentation.  This software is provided "as is" without express or
  98.  *    implied warranty.
  99.  */
  100. /*
  101.  * Copyright 1989, 1990 by the University of Pennsylvania
  102.  *
  103.  * Permission to use, copy, and distribute for non-commercial purposes,
  104.  * is hereby granted without fee, providing that the above copyright
  105.  * notice appear in all copies and that both the copyright notice and this
  106.  * permission notice appear in supporting documentation.
  107.  *
  108.  * The software may be modified for your own purposes, but modified versions
  109.  * may not be distributed.
  110.  *
  111.  * This software is provided "as is" without any express or implied warranty.
  112.  */
  113. /*
  114.  * Copyright 1989, 1990, 1991 Jim Frost
  115.  *
  116.  * Permission to use, copy, modify, distribute, and sell this software
  117.  * and its documentation for any purpose is hereby granted without fee,
  118.  * provided that the above copyright notice appear in all copies and
  119.  * that both that copyright notice and this permission notice appear
  120.  * in supporting documentation.  The author makes no representations
  121.  * about the suitability of this software for any purpose.  It is
  122.  * provided "as is" without express or implied warranty.
  123.  *
  124.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  125.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
  126.  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  127.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  128.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  129.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
  130.  * USE OR PERFORMANCE OF THIS SOFTWARE.
  131.  */
  132.  
  133.  
  134. #include "xv.h"
  135. #include "pcx.h"
  136.  
  137. #define    MAX_DEPTH        8        /* PCX supports up to 8 bits per pixel */
  138. #define PCX_MAXCOLORS    256        /* maximum number of colors in a PCX file */
  139.  
  140.  
  141. static    int PCXError( );
  142. static    int read_pcx_image ( );
  143. static    int pcx_planes_to_pixels ( );
  144. static    int pcx_unpack_pixels ( );
  145. static    void flips( );
  146.  
  147.  
  148. static    byte *imagebuf = NULL;    /* buffer to hold decoded PCX image */
  149.  
  150.  
  151. /*******************************************/
  152. int LoadPCX(fname,nc)
  153.      char *fname;
  154.      int   nc;
  155. /*******************************************/
  156. {
  157.     FILE            *fp;
  158.     byte            *bufptr, *picptr;
  159.     char            msg[86];
  160.     int                bytes_p_line, rv = 0;
  161.     PCX_HEADER        pcxhd;
  162.     register int    i;
  163.  
  164.  
  165.     /* check the depth first */
  166.     if (nc > PCX_MAXCOLORS)
  167.         return( PCXError(sprintf(msg,"cannot handle picture with more than %d colors.",PCX_MAXCOLORS)) );
  168.  
  169.     /* open the file */
  170.     fp = fopen(fname,"r");
  171.     if (!fp)
  172.         return( PCXError("unable to open file for read") );
  173.   
  174.     /* Read pcx header. */
  175.     if (fread(&pcxhd, PCX_HEADERSIZE, 1, fp) != 1) {
  176.         if (fp!=stdin) fclose(fp);
  177.         return( PCXError("unable to read PCX header") );
  178.     }
  179.  
  180.     if ((pcxhd.signature != PCX_MAGIC) || (pcxhd.version > PCX_LAST_VER)) {
  181.         if (fp!=stdin) fclose(fp);
  182.         return( PCXError("not a PCX file") );
  183.     }
  184.  
  185.     if (pcxhd.encoding != PCX_RLL) {
  186.         if (fp!=stdin) fclose(fp);
  187.         return( PCXError("not run-length encoded PCX file") );
  188.     }
  189.  
  190.     if (pcxhd.bitsperpix > MAX_DEPTH) {
  191.         if (fp!=stdin) fclose(fp);
  192.         return( PCXError(sprintf(msg,"cannot handle picture depth > %d",MAX_DEPTH)) );
  193.     }
  194.  
  195.  
  196.     /* Calculate image size */
  197.  
  198.     flips((byte *) &pcxhd.Xleft);
  199.     flips((byte *) &pcxhd.Ytop);
  200.     flips((byte *) &pcxhd.Xright);
  201.     flips((byte *) &pcxhd.Ybottom);
  202.  
  203.     flips((byte *) &pcxhd.linesize);
  204.  
  205.     pWIDE = pcxhd.Xright - pcxhd.Xleft + 1;
  206.     pHIGH = pcxhd.Ybottom - pcxhd.Ytop + 1;
  207.  
  208.     SetISTR(ISTR_FORMAT,"PC Paintbrush, %d %s, %d %s per pixel.",
  209.             pcxhd.planes, (pcxhd.planes==1) ? "plane":"planes",
  210.             pcxhd.bitsperpix, (pcxhd.bitsperpix==1) ? "bit":"bits");
  211.  
  212.  
  213.     /*
  214.      * Read colormap if less than 8 bits per pixel.
  215.      */
  216.  
  217.     if (pcxhd.bitsperpix < 8) {
  218.  
  219.         register int all_zeros = 1;
  220.  
  221.         for (i=0; i < 16; i++) {
  222.             r[i] = pcxhd.PCXpalette[i][0];
  223.             g[i] = pcxhd.PCXpalette[i][1];
  224.             b[i] = pcxhd.PCXpalette[i][2];
  225.  
  226.             all_zeros = all_zeros && (r[i] == 0) && (g[i] == 0) && (b[i] == 0);
  227.         }
  228.  
  229.         /*
  230.          * if the color palette contained all zeros, set to white and black
  231.          * as default colors.
  232.          */
  233.         if (all_zeros) {
  234.             r[0] = g[0] = b[0] = 255;    /* white */
  235.             r[1] = g[1] = b[1] = 0;        /* black */
  236.         }
  237.     }
  238.  
  239.  
  240.     /* allocate memory for decoded image buffer */
  241.  
  242.     imagebuf = (byte *) malloc(pcxhd.linesize * pHIGH * pcxhd.planes);
  243.     if (imagebuf == NULL) 
  244.         FatalError("unable to malloc PCX buffer");
  245.  
  246.  
  247.     /* Read compressed bitmap. */
  248.  
  249.     if (rv = read_pcx_image( fp, imagebuf, &pcxhd, pHIGH )) {
  250.         if (imagebuf) free(imagebuf);
  251.         if (fp!=stdin) fclose(fp);
  252.         return rv;
  253.     }
  254.  
  255.  
  256.     /*
  257.      * Read colormap if 8 bits per pixel.
  258.      */
  259.  
  260.     if (pcxhd.bitsperpix == 8) {
  261.         register int ch;
  262.  
  263.         if ((ch = getc(fp)) == PCX_256COLORS_MAGIC) {
  264.             for (i = 0; i < PCX_MAXCOLORS; i++) {
  265.                 if ((ch = getc(fp)) != EOF) r[i] = ch; else break;
  266.                 if ((ch = getc(fp)) != EOF) g[i] = ch; else break;
  267.                 if ((ch = getc(fp)) != EOF) b[i] = ch; else break;
  268.             }
  269.  
  270.             if (i != PCX_MAXCOLORS) {
  271.                 if (imagebuf) free(imagebuf);
  272.                 if (fp!=stdin) fclose(fp);
  273.                 return( PCXError("256-colormap truncated"));
  274.             }
  275.  
  276.         } else {
  277.             if (imagebuf) free(imagebuf);
  278.             if (fp!=stdin) fclose(fp);
  279.             return( PCXError("no 256-colormap for 8 bit picture") );
  280.         }
  281.     }
  282.  
  283.     /* we won't be reading anymore data in */
  284.     if (fp!=stdin) fclose(fp);
  285.  
  286.  
  287.     /* Allocate memory for picture */
  288.  
  289.     pic = (byte *) malloc(pWIDE * pHIGH);
  290.     if (pic == NULL) {
  291.         if (imagebuf) free(imagebuf);
  292.         FatalError("unable to malloc PCX picture");
  293.     }
  294.  
  295.  
  296.     /* Convert from PCX to one byte per pixel */
  297.  
  298.     bytes_p_line = pcxhd.linesize * pcxhd.planes;
  299.  
  300.     for (picptr = pic, bufptr = imagebuf, i = 0;
  301.          i < pHIGH;
  302.          i++, picptr += pWIDE, bufptr += bytes_p_line) {
  303.  
  304.         if (pcxhd.planes == 1) {
  305.             if (rv = pcx_unpack_pixels(picptr, bufptr, &pcxhd))
  306.                 break;
  307.         } else {
  308.             if (rv = pcx_planes_to_pixels(picptr, bufptr, &pcxhd))
  309.                 break;
  310.         }
  311.     }
  312.  
  313.     free(imagebuf);
  314.     return rv;
  315. }
  316.  
  317.  
  318.  
  319.  
  320.  
  321. /*
  322.  *  read_pcx_image
  323.  *
  324.  *    Load PCX file into the buffer passed in.
  325.  *
  326.  *    Returns 0 if success, -1 if failure.
  327.  */
  328.  
  329. static int
  330. read_pcx_image(fp, buf, phd, height)
  331. FILE            *fp;
  332. register byte    *buf;
  333. PCX_HEADER        *phd;
  334. unsigned int    height;
  335. {
  336.     /*
  337.      * Goes like this: Read a byte.  If the two high bits are set,
  338.      * then the low 6 bits contain a repeat count, and the byte to
  339.      * repeat is the next byte in the file.  If the two high bits are
  340.      * not set, then this is the byte.
  341.      */
  342.  
  343.     register int count, nbytes, c;
  344.  
  345.     nbytes    = phd->linesize * phd->planes * height;
  346.  
  347.     while (nbytes > 0)
  348.     {
  349.         c = getc(fp);
  350.         if (c == EOF)
  351.             return( PCXError("unexpected EOF in file") );
  352.  
  353.         if ((c & 0xc0) != 0xc0) {
  354.             *buf++ = (byte)c;
  355.             --nbytes;
  356.             continue;
  357.         }
  358.  
  359.         count = c & 0x3f;
  360.         if (count > nbytes)
  361.             (void) PCXError("repeat count spans end of image");
  362.  
  363.         c = getc(fp);
  364.         if (c == EOF)
  365.             return( PCXError("unexpected EOF in file") );
  366.  
  367.         nbytes -= count;
  368.         while (--count >= 0)
  369.             *buf++ = (byte)c;
  370.     }
  371.  
  372.     return 0;
  373. }
  374.  
  375.  
  376.  
  377.  
  378.  
  379. /*
  380.  * convert packed pixel format into 1 pixel per byte
  381.  */
  382. static int
  383. pcx_unpack_pixels(pixels, bitplanes, phd)
  384. register byte *pixels;
  385. register byte *bitplanes;
  386. PCX_HEADER      *phd;
  387. {
  388.     register int bits, bytesperline = phd->linesize;
  389.  
  390.     if (phd->planes != 1)
  391.         return( PCXError("can't handle packed pixels with more than 1 plane") );
  392.  
  393.     switch (phd->bitsperpix) {
  394.       case 8:
  395.         while (--bytesperline >= 0)
  396.             *pixels++ = *bitplanes++;
  397.         break;
  398.  
  399.       case 4:
  400.         while (--bytesperline >= 0) {
  401.             bits      = *bitplanes++;
  402.             *pixels++ = (bits >> 4) & 0x0f;
  403.             *pixels++ = (bits     ) & 0x0f;
  404.         }
  405.         break;
  406.  
  407.       case 2:
  408.         while (--bytesperline >= 0) {
  409.             bits      = *bitplanes++;
  410.             *pixels++ = (bits >> 6) & 0x03;
  411.             *pixels++ = (bits >> 4) & 0x03;
  412.             *pixels++ = (bits >> 2) & 0x03;
  413.             *pixels++ = (bits     ) & 0x03;
  414.         }
  415.         break;
  416.  
  417.       case 1:
  418.             /*
  419.              * in this case, 1 == white, 0 == black, so reverse them.
  420.              */
  421.         while (--bytesperline >= 0) {
  422.             bits      = *bitplanes++;
  423.             *pixels++ = ((bits & 0x80) == 0);
  424.             *pixels++ = ((bits & 0x40) == 0);
  425.             *pixels++ = ((bits & 0x20) == 0);
  426.             *pixels++ = ((bits & 0x10) == 0);
  427.             *pixels++ = ((bits & 0x08) == 0);
  428.             *pixels++ = ((bits & 0x04) == 0);
  429.             *pixels++ = ((bits & 0x02) == 0);
  430.             *pixels++ = ((bits & 0x01) == 0);
  431.         }
  432.         break;
  433.  
  434.       default:
  435.         return( PCXError("unsupported number of bits per pixel") );
  436.         break;
  437.     }
  438.  
  439.     return 0;
  440. }
  441.  
  442.  
  443.  
  444. /*
  445.  * convert multi-plane format into 1 pixel per byte
  446.  */
  447. static int
  448. pcx_planes_to_pixels(pixels, bitplanes, phd)
  449. register byte *pixels;
  450. register byte *bitplanes;
  451. PCX_HEADER      *phd;
  452. {
  453.     register int            i, npixels;
  454.     register byte            *p;
  455.     register unsigned int    bytesperline = phd->linesize;
  456.  
  457.     if (phd->planes > 4)
  458.         return( PCXError("can't handle more than 4 planes") );
  459.  
  460.     if (phd->bitsperpix != 1)
  461.         return( PCXError("can't handle more than 1 bit per pixel") );
  462.  
  463.     /*
  464.      * clear the pixel buffer
  465.      */
  466.     npixels = (bytesperline * 8) / phd->bitsperpix;
  467.     p = pixels;
  468.     while (--npixels >= 0)
  469.         *p++ = 0;
  470.  
  471.     /*
  472.      * do the format conversion
  473.      */
  474.     for (i = 0; i < phd->planes; i++) {
  475.  
  476.         register int j, pixbit, bits, mask;
  477.  
  478.         for (p = pixels, pixbit = (1 << i), j = 0;
  479.              j < bytesperline;
  480.              j++) {
  481.  
  482.             bits = *bitplanes++;
  483.             if (bits & 0x80) *p++ |= pixbit; else p++;
  484.             if (bits & 0x40) *p++ |= pixbit; else p++;
  485.             if (bits & 0x20) *p++ |= pixbit; else p++;
  486.             if (bits & 0x10) *p++ |= pixbit; else p++;
  487.             if (bits & 0x08) *p++ |= pixbit; else p++;
  488.             if (bits & 0x04) *p++ |= pixbit; else p++;
  489.             if (bits & 0x02) *p++ |= pixbit; else p++;
  490.             if (bits & 0x01) *p++ |= pixbit; else p++;
  491.         }
  492.     }
  493.  
  494.     return 0;
  495. }
  496.  
  497.  
  498.  
  499. /*
  500.  *    PCXError
  501.  */
  502. static int
  503. PCXError(st)
  504. char *st;
  505. {
  506.     /*if (DEBUG)*/
  507.         fprintf(stderr,"%s: LoadPCX() - %s\n",cmd,st);
  508.  
  509.     SetISTR(ISTR_WARNING,"%s: LoadPCX() - %s",cmd,st);
  510.     Warning();
  511.  
  512.     return -1;
  513. }
  514.  
  515.  
  516.  
  517. static void flips(p)
  518. byte *p;
  519. {
  520.     register byte t = p[0]; 
  521.     p[0] = p[1];
  522.     p[1] = t;
  523. }
  524.